package com.dwin.dingnuo.ui;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.dwin.dingnuo.R;
import com.dwin.dingnuo.http.DwinConstants;
import com.dwin.dingnuo.http.MyRetrofit;
import com.dwin.dingnuo.http.beans.BackModel;
import com.dwin.dingnuo.http.beans.UserBean;
import com.dwin.dingnuo.http.request.ReqDeviceDelete;
import com.dwin.dingnuo.http.response.HomeDevice;
import com.dwin.dingnuo.http.response.RspDeviceList;
import com.dwin.dingnuo.ui.base.BaseActivity;
import com.dwin.dingnuo.ui.detail.DeviceDetailActivity;
import com.dwin.dingnuo.ui.system.EditPasswordActivity;
import com.dwin.dingnuo.ui.system.LoginActivity;
import com.dwin.dingnuo.utils.ActivityUtils;
import com.dwin.dingnuo.utils.Constants;
import com.dwin.dingnuo.utils.DisplayUtil;
import com.dwin.dingnuo.utils.ToastUtil;
import com.dwin.dingnuo.views.AddDeviceDialog;
import com.dwin.dingnuo.views.DwinDialog;
import com.dwin.dingnuo.views.DwinInputDialogV2;
import com.dwin.dingnuo.views.DwinOfflineDialog;
import com.dwin.dingnuo.views.NetLoadingDialog;
import com.example.qrcode.Constant;
import com.google.gson.Gson;

import org.litepal.LitePal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import okhttp3.RequestBody;
import retrofit2.Response;


/**
 * 设备列表页面
 */

/**
 * 主页面, 显示设备列表，在线离线台数
 */
public class MainActivity extends BaseActivity implements View.OnClickListener {
    private static final String TAG = "MainActivity";
    private TextView tv_online, tv_offline;
    private GridView gv_home_devices;
    private DeviceAdapter mAdapter;
    private RelativeLayout rl_home_nodata;

    private boolean isShowDelete = false; // 是否显示删除键
    private List<HomeDevice> devices = new ArrayList<>();

    private SwipeRefreshLayout swipeRefreshLayout;
    private boolean isFirstLoad = true; // 是否是第一次刷新
    private int pageNo = 1; // 页码
    private boolean mHasMore = true; // 是否有更多数据

    private static final int REQUEST_INTERVAL_10S = 10 * 1000; // 10s 列表刷新请求一下


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
        // refreshDeviceList();
    }

    @Override
    protected void initViews() {
        tv_online = findViewById(R.id.tv_online);
        tv_offline = findViewById(R.id.tv_offline);
        findViewById(R.id.btn_add_devices).setOnClickListener(this);
        swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
        swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.color_3a89f3));
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                pageNo = 1;
                refreshDeviceList(); // 重新请求列表
            }
        });

        gv_home_devices = findViewById(R.id.gv_devices);
        mAdapter = new DeviceAdapter(mContext, devices);
        gv_home_devices.setAdapter(mAdapter);
        rl_home_nodata = findViewById(R.id.rl_home_nodata);

        gv_home_devices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                HomeDevice device = devices.get(position);
                if (device != null) {
                    if (device.device_alive_or_dead == 0) {
                        showOfflineDialog();
                    } else {
                        Bundle bundle = new Bundle();
                        bundle.putSerializable("device", device);
                        ActivityUtils.switchActivity(mContext, DeviceDetailActivity.class, bundle);
                    }
                }
            }
        });
        mAdapter.setOnAdapterListener(new DeviceAdapter.OnAdapterListener() {
            @Override
            public void onClkDelete(int position) {
                mAdapter.setIsShowDelete(false);
                actionDeleteDevice(devices.get(position).id, position);
            }
        });
        // 长按删除设备
        gv_home_devices.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                // 删除设备逻辑，后台控制。
                isShowDelete = !isShowDelete;
                mAdapter.setIsShowDelete(isShowDelete);
                return true;
            }
        });

        gv_home_devices.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
            }
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                // Log.d(TAG, "firstVisibleItem: " + firstVisibleItem);
                // Log.d(TAG, "visibleItemCount: " + visibleItemCount);
                // Log.d(TAG, "totalItemCount: " + totalItemCount);

                if (devices.size() >= PAGE_SIZE) { // 页码有数据
                    if (view.getLastVisiblePosition() == (view.getCount() - 1)) {   // 判断滚动到底部
                        if (mHasMore) { // 存在更多数据
                            pageNo++;
                            refreshDeviceList(); // 获取第二页数据
                        }
                    }
                }
            }
        });
    }

    Handler handler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            // 延时10s，要刷新页面设备列表的数据
            handler.postDelayed(this, REQUEST_INTERVAL_10S);
            refreshDeviceList();
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        handler.postDelayed(runnable, 0);// 立即执行一次runnable.
    }

    @Override
    protected void onPause() {
        super.onPause();
        handler.removeCallbacks(runnable);
    }

    /**
     * 通过设备二维码：添加设备 postAddDeviceByQRCode
     */
    private void postAddDeviceByQRCode(String qrCode, String name) {
        if (!isNetworkConnected(mContext)) {
            ToastUtil.toastShort(mContext, R.string.net_error);
            return;
        }
        Map<String, String> info = new HashMap<>();
        info.put("QRCode", qrCode);
        info.put("name", name);
        Gson gson = new Gson();
        String obj = gson.toJson(info);
        RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), obj);

        MyRetrofit.getInstance().addDeviceByQRCode(mUser.auth, language, body, new retrofit2.Callback<BackModel>() {
            @Override
            public void onResponse(retrofit2.Call<BackModel> call, Response<BackModel> response) {
                String msg = response.body().message;
                if (DwinConstants.HTTP_OK == response.body().code) {
                    // 添加设备成功
                    ToastUtil.toastShort(mContext, getResources().getString(R.string.device_added));
                    refreshDeviceList();
                } else if (DwinConstants.HTTP_TOKEN_402 == response.body().code || DwinConstants.HTTP_TOKEN_100002 == response.body().code) {
                    userLogout(); // 用户已在别处登陆
                } else { //
                    ToastUtil.toastShort(mContext, msg);
                }
            }

            @Override
            public void onFailure(retrofit2.Call<BackModel> call, Throwable t) {
            }
        });
    }


    /**
     * 删除设备，删除后，要刷新列表重新获取列表的数据
     */
    private void actionDeleteDevice(int deviceId, final int position) {
        if (!isNetworkConnected(mContext)) {
            ToastUtil.toastShort(mContext, R.string.net_error);
            return;
        }
        NetLoadingDialog.showprogress(mContext, true);
        ReqDeviceDelete info = new ReqDeviceDelete();
        info.device_id = deviceId;
        String obj = new Gson().toJson(info);
        RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), obj);

        MyRetrofit.getInstance().deviceDelete(mUser.auth, language, body, new retrofit2.Callback<BackModel>() {
            @Override
            public void onResponse(retrofit2.Call<BackModel> call, Response<BackModel> response) {
                NetLoadingDialog.dismissprogress();
                if (DwinConstants.HTTP_OK == response.body().code) {
                    if (position < devices.size()) {
                        devices.remove(position);
                        mAdapter.setData(devices);
                        mAdapter.setIsShowDelete(false); // item 不显示删除按钮
                        // 初始状态恢复
                        mHasMore = true;
                        pageNo = 1;
                        refreshDeviceList(); // 重新请求，更新UI
                    }
                } else if (DwinConstants.HTTP_TOKEN_100002 == response.body().code) {
                    userLogout();
                } else {
                    ToastUtil.toastShort(mContext, response.body().message);
                }
            }

            @Override
            public void onFailure(retrofit2.Call<BackModel> call, Throwable t) {
                NetLoadingDialog.dismissprogress();
            }
        });
    }


    // 请求设备列表
    private void refreshDeviceList() {
        if (!isNetworkConnected(mContext)) {
            ToastUtil.toastShort(mContext, R.string.net_error);
            return;
        }
        if (isFirstLoad) {
            swipeRefreshLayout.setRefreshing(true);
            isFirstLoad = false;
        }
        Map<String, String> header = new HashMap<>();
        header.put("platform", MyRetrofit.platform);
        header.put("language", language);
        header.put("auth", mUser.auth);

        Map<String, String> queries = new HashMap<>();
        queries.put("page", String.valueOf(pageNo));
        queries.put("perPage", String.valueOf(PAGE_SIZE));
        queries.put("device_alive_or_dead", "-1"); // 状态1:上线0：下线，-1:是所有设备
        queries.put("product_id", "-1"); // 分类id。-1：所有,4:温控器，8：空净屛
        queries.put("product_model_id", "-1"); //  子分类id。-1：所有，

       // Log.e(TAG, "refreshDeviceList: page"+ pageNo);
        MyRetrofit.getInstance().getDeviceList(header, queries, new retrofit2.Callback<RspDeviceList>() {
            @Override
            public void onResponse(retrofit2.Call<RspDeviceList> call, Response<RspDeviceList> response) {
                if (swipeRefreshLayout.isRefreshing()) {
                    swipeRefreshLayout.setRefreshing(false);
                }
                if (response.body() == null) {
                    ToastUtil.toastShort(mContext, R.string.server_error_wait);
                    return;
                }
                if (DwinConstants.HTTP_OK == response.body().code) {
                    List<HomeDevice> temp = (ArrayList<HomeDevice>) response.body().data.data;
                    // Log.e(TAG, "refreshDeviceList: temp size: "+ temp.size());

                    if (temp.size() < PAGE_SIZE) {
                        mHasMore = false;
                    }
                    if (pageNo == 1) {
                        devices = temp;
                    } else {
                        devices.addAll(temp);
                    }
                    mAdapter.setData(devices);
                    mAdapter.setIsShowDelete(false);
                    if (devices != null && devices.size() > 0) {
                        rl_home_nodata.setVisibility(View.GONE);
                        gv_home_devices.setVisibility(View.VISIBLE);
                    } else {
                        rl_home_nodata.setVisibility(View.VISIBLE);
                        gv_home_devices.setVisibility(View.GONE);
                    }
                    // 设置设备数量
                    String onLine = getResources().getString(R.string.home_device_online);
                    String offLine = getResources().getString(R.string.home_device_offline);
                    tv_online.setText(String.format(onLine, response.body().data.device_online_total));
                    tv_offline.setText(String.format(offLine, response.body().data.device_dead_total));
                } else if (DwinConstants.HTTP_TOKEN_100002 == response.body().code) {
                    userLogout();
                } else {
                    ToastUtil.toastShort(mContext, response.body().message);
                }
            }

            @Override
            public void onFailure(retrofit2.Call<RspDeviceList> call, Throwable t) {
                if (swipeRefreshLayout.isRefreshing()) {
                    swipeRefreshLayout.setRefreshing(false);
                }
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_add_devices: // 一键配网，添加设备，取消。
                showAddDialog();
                break;
        }
    }

    private static final int CODE_QRCODE = 999;
    private static final int CODE_CONFIG_NET = 1000;
    private static final int CODE_ADD = 1001;

    private void showAddDialog() {
        AddDeviceDialog mDialog = new AddDeviceDialog(this);
        mDialog.popSelectDialog();
        mDialog.setCallBack(new AddDeviceDialog.ClickBack() {
            @Override
            public void clickOption00() { // 一键配网
//                Intent intent = new Intent(mContext, ConfigureNetAirKissActivity.class);
//                startActivityForResult(intent, CODE_CONFIG_NET);
            }

            @Override
            public void clickOption01() { // 扫码设备二维码
                if (hasPermission(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    doCameraPermission();
                } else {
                    requestPermissions(Constants.CAMERA_CODE, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE);
                }
            }

            @Override
            public void clickOption02() {
                showExitDialog();
            }

            @Override
            public void clickOption03() {
                // 修改密码
                ActivityUtils.switchActivity(mContext, EditPasswordActivity.class);
            }
        });
    }

    // 退出登录
    private void showExitDialog() {
        final DwinDialog dialog = new DwinDialog(mContext, R.style.DialogTheme);
        dialog.setTip(getResources().getString(R.string.exit_app))
                .setContent(getResources().getString(R.string.logout_dwin_app))
                .setPositiveTxt(getResources().getString(R.string.confirm))
                .setNegativeTxt(getResources().getString(R.string.cancel));
        dialog.setDialogListener(new DwinDialog.MyDialogListener() {
            @Override
            public void onClick(View view) {
                switch (view.getId()) {
                    case R.id.tv_positive: // 确定
                        LitePal.deleteAll(UserBean.class); // 先删除所有用户数据
                        Intent intent = new Intent(mContext, LoginActivity.class);
                        intent.setFlags(intent.FLAG_ACTIVITY_CLEAR_TASK | intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                        break;
                    case R.id.tv_negative:
                        break;
                    default:
                        break;
                }
                dialog.dismiss();
            }
        });
        dialog.show();
    }


    @Override
    public void doCameraPermission() {
        actionScanCode();
    }

    private void actionScanCode() {
        Intent intent = new Intent(mContext, com.example.qrcode.ScannerActivity.class);
        intent.putExtra(Constant.EXTRA_SCANNER_FRAME_WIDTH, DisplayUtil.dip2px(mContext, 257));
        intent.putExtra(Constant.EXTRA_SCANNER_FRAME_HEIGHT, DisplayUtil.dip2px(mContext, 257));
        intent.putExtra(Constant.EXTRA_SCANNER_FRAME_TOP_PADDING, DisplayUtil.dip2px(mContext, 136));
        intent.putExtra(Constant.EXTRA_IS_ENABLE_SCAN_FROM_PIC, true);
        startActivityForResult(intent, CODE_QRCODE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CODE_QRCODE && resultCode == Activity.RESULT_OK) { // 二维码扫描结果
            if (data != null) {
                String result = data.getExtras().getString(Constant.EXTRA_RESULT_CONTENT);
                Log.d(TAG, "result:" + result);
                if (result.contains("m=") && result.contains("_")) {
                    String[] divs = result.split("_");
                    if (divs.length >= 4) {
                        showInputDialog(result);
                    }
                } else {
                    ToastUtil.toastLong(mContext, R.string.qrcode_error);
                }
            }
        } else if (requestCode == CODE_CONFIG_NET && resultCode == Activity.RESULT_OK) {
            String device_bssid = data.getExtras().getString("device_bssid");
            Log.d(TAG, "CODE_CONFIG_NET:" + device_bssid);
        } else if (requestCode == CODE_ADD && resultCode == Activity.RESULT_OK) {
        }
    }

    // 弹出名称输入框
    private void showInputDialog(final String result) {
        final DwinInputDialogV2 dialog = new DwinInputDialogV2(mContext, R.style.DialogTheme);
        dialog.setMyTitle("编辑站点")
                .setMyName("")
                .setMyNameHint("请输入站点名称");
        dialog.setDialogListener(new DwinInputDialogV2.MyDialogListener() {
            @Override
            public void onClickPositive(String name) {
                dialog.dismiss();
                Log.d(TAG, "showInputDialog confirm btn:" + name);
                postAddDeviceByQRCode(result, name);
            }
        });
        dialog.show();
    }

    // 弹出离线对话框
    private void showOfflineDialog() {
        final DwinOfflineDialog dialog = new DwinOfflineDialog(mContext, R.style.DialogTheme);
        dialog.setDialogListener(new DwinOfflineDialog.MyDialogListener() {
            @Override
            public void onClick(View view) {
                Log.d(TAG, "click confirm btn");
                dialog.dismiss();
            }
        });
        dialog.show();
    }


    private long firstTime = 0;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        long secondTime = System.currentTimeMillis();
        if (isShowDelete) {
            isShowDelete = false;
            mAdapter.setIsShowDelete(isShowDelete);
            return true;
        }
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (secondTime - firstTime < 2000) {
                System.exit(0);
            } else {
                Toast.makeText(MainActivity.this, R.string.press_again_2exit, Toast.LENGTH_SHORT).show();
                firstTime = System.currentTimeMillis();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}
